<template>
  <div>
    <ZgDialog
      :width="view.width"
      :top="view.top"
      :title="view.title"
      v-model="visible"
      @ok="save">
      <div :style="{padding:`${layout.视图边距}px`}">
        <a-row :gutter="layout.左右间距">
          <a-col :offset="c.offset" :span="c.span" v-for="(c,i) in columns" :key="`column${i}`">
            <div v-if="obj!==null" :class="layout.标签对齐==='top'?'':'flx-s'" :style="{marginBottom:`${layout.上下间距}px`}">
              <div :class="layout.标签对齐==='right'?'tar':'tal'" class="mr10 flx-s" :style="{width:`${layout.标签宽度}px`}">
                <ZgCheckbox class="mr10" v-model="obj[`${c.code}_ck`]"></ZgCheckbox>
                {{ c.name }}
              </div>
              <div class="flx-1" :class="layout.标签对齐==='top'?'mt10':''">
                <ZgInput v-model="obj[c.code]" v-if="c.compType==='单行文本'"></ZgInput>
                <ZgNumber v-model="obj[c.code]" v-if="c.compType==='整数'"></ZgNumber>
                <ZgCheckbox v-model="obj[c.code]" v-if="c.compType==='单选框'"></ZgCheckbox>
                <ZgMultiple v-model="obj[c.code]" v-if="c.compType==='多选'" :code="c.extra.字典类型"></ZgMultiple>
                <ZgDatePicker v-model="obj[c.code]" v-if="c.compType==='日期'"></ZgDatePicker>
                <ZgDictionary v-model="obj[c.code]" v-if="c.compType==='字典'" :code="c.extra.字典类型"></ZgDictionary>
                <ZgSwitch v-model="obj[c.code]" v-if="c.compType==='开关'"></ZgSwitch>
                <ZgUpImg v-model="obj[c.code]" v-if="c.compType==='图片'"></ZgUpImg>
              </div>
            </div>
          </a-col>
        </a-row>
      </div>
    </ZgDialog>
  </div>
</template>
<script>
export default {
  props: {
    view: {
      type: Object,
      default: () => {
        return { width: '40%', top: '5%', title: '批量修改数据' }
      }
    },
    layout: {
      type: Object,
      default: () => {
        return { 视图边距: 10, 标签宽度: 120, 标签对齐: 'right', 左右间距: 10, 上下间距: 10 }
      }
    },
    columns: {
      type: Array,
      default: () => {
        return [
          { name: '性别', code: 'sex', compType: '字典', isNeed: true, offset: 0, span: 24, defaultVal: '1', extra: { 字典类型: 'sex' } },
          { name: '姓名', code: 'name', compType: '单行文本', isNeed: true, offset: 0, span: 24, defaultVal: 'zxb', regex: '', errorMsg: '' },
          { name: '年龄', code: 'age', compType: '整数', isNeed: true, offset: 0, span: 24, defaultVal: 0 },
          { name: '是否测试账号', code: 'is_test', compType: '单选框', isNeed: true, offset: 0, span: 24, defaultVal: false },
          { name: '政治面貌', code: 'political', compType: '多选', isNeed: true, offset: 0, span: 24, defaultVal: '', extra: { 字典类型: 'political' } },
          { name: '是否启用', code: 'is_use', compType: '开关', isNeed: true, offset: 0, span: 24, defaultVal: false },
          { name: '生日', code: 'birth', compType: '日期', isNeed: true, offset: 0, span: 24, defaultVal: '2025-05-22' }
        ]
      }
    },
    formulas: {
      type: Array,
      default: () => {
        return [
          { triggerMode: '初始化时', name: '公式1', content: 'console.log("init");' },
          { triggerMode: '数据变化时', name: '公式2', content: 'console.log("update");' },
          { triggerMode: '提交时', name: '公式3', content: 'console.log("submit");' }
        ]
      }
    },
    validUrl: {
      type: String,
      default: ''
    },
    saveUrl: {
      type: String,
      default: ''
    }
  },
  data () {
    return {
      visible: false,
      ids: [],
      obj: null
    }
  },
  watch: {
    obj: {
      handler (newVal, oldVal) {
        if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
          console.log('数据变化时执行公式')
          this.doFormula(this.formulas.filter(t => {
            return t.triggerMode === '数据变化时'
          }))
        }
      },
      deep: true
    }
  },
  mounted () {
    this.initData()
  },
  methods: {
    open (ids) {
      this.ids = ids
      this.visible = true
    },
    doFormula (formulas) {
      if (!formulas || formulas.length === 0) { return }
      const arr = []
      formulas.forEach(t => {
        try {
          // eslint-disable-next-line no-eval
          eval(t.content)
        } catch (e) {
          arr.push(t)
        }
      })
      if (arr.length > 0) {
        this.$error({ title: `有${arr.length}个公式执行错误：${arr.map(t => t.name).join('、')}` })
        return false
      } else {
        return true
      }
    },
    initData () {
      // 初始化默认值
      this.obj = this.columns.reduce((x, item) => {
        x[item.code] = item.defaultVal
        x[`${item.code}_ck`] = false
        return x
      }, {})
      console.log('初始化时执行公式')
      this.doFormula(this.formulas.filter(t => {
        return t.triggerMode === '初始化时'
      }))
    },
    save () {
      if (this.saveUrl.length === 0) {
        this.$error({ title: `未设置保存接口` })
        return
      }
      // 验证是否选择了设置的数据
      const hasCheckedProperty = this.columns.some(c => {
        return this.obj[`${c.code}_ck`] === true
      })
      if (!hasCheckedProperty) {
        this.$error({ title: '请选择要设置的属性' })
        return
      }

      // 选择的属性必须要设置值
      const checkedPropArray = this.columns.filter(c => {
        return this.obj[`${c.code}_ck`] === true
      })
      for (const i in checkedPropArray) {
        const column = checkedPropArray[i]
        const value = this.obj[column.code]
        if (['单选框', '开关'].includes(column.compType)) {
          continue
        } else if (['整数', '浮点数'].includes(column.compType)) {
          if (!value || value === 0) {
            this.$error({ title: `${column.name}不能为0` })
            return
          }
        } else {
          if (!value || value.length === 0) {
            this.$error({ title: `${column.name}为必填项` })
            return
          }
        }
      }

      // 选择的属性验证正则，只验证单行文本
      for (const i in this.columns) {
        const column = this.columns[i]
        const value = this.obj[column.code]
        if (column.compType === '单行文本' && column.regex && column.regex.length > 0) {
          const reg = new RegExp(column.regex)
          if (!reg.test(value)) {
            this.$error(column.errorMsg)
            return
          }
        }
      }
      // 提交前执行公式
      console.log('提交前执行公式')
      this.doFormula(this.formulas.filter(t => {
        return t.triggerMode === '提交时'
      }))
      // 远程接口验证
      const param = Object.assign({ ids: this.ids }, this.obj)
      if (this.validUrl && this.validUrl.length > 0) {
        this.$http.post(this.validUrl, param, () => {
          this.realSave(param)
        }, (exp) => {
          console.log('remote-valid-exp', exp)
          this.$error({ title: '远程验证接口调用失败，请检查接口地址' })
        })
      } else {
        this.realSave(param)
      }
    },
    realSave (param) {
      this.$http.post(this.saveUrl, param, () => {
        this.visible = false
        this.$emit('ok')
      })
    }
  }
}
</script>

<style lang="scss" scoped>
</style>
